
#include "type.h"
#include "sim_pwm_config.h"
#include "string.h"

typedef struct {
    volatile uint16_t duty;             
    volatile uint16_t period;           
    volatile uint16_t counter;
    volatile bool_t enbable;
} SIM_PWM_STRUCT;

static volatile SIM_PWM_STRUCT PWMS[PWM_NUM_MAX];

void sim_pwm_init(void)
{
	volatile uint8_t i;
	memset(PWMS, 0, sizeof(SIM_PWM_STRUCT)*PWM_NUM_MAX);
    for(i = 0; i < PWM_NUM_MAX; i++) {
        PWMS[i].period = 1;
	}

	sim_pwm_hal_init_config();
}

void sim_pwm_start(uint8_t pwm_num)
{
    PWMS[pwm_num].enbable = 1;
    if(PWMS[pwm_num].duty == 0){
        sim_pwm_output_low_config(pwm_num);
    }
}

void sim_pwm_stop(uint8_t pwm_num)
{
    PWMS[pwm_num].enbable = 0;
    PWMS[pwm_num].counter = 0;
}

void sim_pwm_set_period(uint8_t pwm_num, uint16_t period)   //1~ffff ticks
{
    if((period > 0)&&(period >= PWMS[pwm_num].duty)){
        PWMS[pwm_num].period = period;
    }
}

void sim_pwm_set_duty(uint8_t pwm_num, uint16_t duty)       //0~ffff ticks
{
    if(duty <=  PWMS[pwm_num].period){
        PWMS[pwm_num].duty = duty;
    }
}

static volatile uint8_t i;
void sim_pwm_tick_handler(void)
{
    for(i = 0; i < PWM_NUM_MAX; i++) {
        if(PWMS[i].enbable){
            PWMS[i].counter++;
            if(PWMS[i].counter >= PWMS[i].period){
                PWMS[i].counter = 0;
                if(PWMS[i].duty > 0){
                    sim_pwm_output_high_config(i);
                }
            }
            if(PWMS[i].counter >= PWMS[i].duty){
                sim_pwm_output_low_config(i);
            } 
        }
    }
}